﻿Imports Framework.Data

Public Class FSettings
    Private mCurrent As SettingsControlHolder
    Private mHolders As New Generic.Dictionary(Of String, SettingsControlHolder)
    Private mSaved As Boolean = False

    Public Class Provider
        Implements Framework.Settings.Provider.IProvider

        Public Sub Show(ByVal owner As System.Windows.Forms.IWin32Window) Implements Framework.Settings.Provider.IProvider.Show
            Dim clsView As New FSettings
            clsView.Show(owner)
        End Sub

        Public Function ShowDialog(ByVal owner As System.Windows.Forms.IWin32Window, ByVal tabKeys() As String) As Boolean Implements Framework.Settings.Provider.IProvider.ShowDialog
            Dim clsView As New FSettings
            Return clsView.ShowDialog(owner, tabKeys)
        End Function
    End Class

    Public Shadows Sub Show(ByVal owner As IWin32Window)
        CreateAndAddTabs(Nothing)

        ListView1.Items(0).Selected = True
        ShowSettingsControl(CType(ListView1.Items(0).Tag, SettingsControlHolder))
        For Each clsHolder As SettingsControlHolder In mHolders.Values
            If clsHolder.IsLoaded Then clsHolder.Control.BeforeShow()
        Next
        MyBase.Show(owner)
    End Sub

    Private Sub CreateAndAddTabs(ByVal tabKeys() As String)
        Dim aRegisteredTabs As Generic.Dictionary(Of String, System.Type)
        aRegisteredTabs = Framework.Settings.Provider.GetAllRegisteredTabs
        If tabKeys Is Nothing Then tabKeys = aRegisteredTabs.Keys.ToArray

        For Each strTabKey As String In tabKeys
            Dim clsType As System.Type = aRegisteredTabs.Item(strTabKey)
            Dim clsControl As Framework.Settings.ISettingsControl = CType(System.Activator.CreateInstance(clsType), Framework.Settings.ISettingsControl)
            AddTab(clsControl)
        Next
    End Sub
    Public Shadows Function ShowDialog(ByVal owner As IWin32Window, ByVal tabKeys() As String) As Boolean
        CreateAndAddTabs(tabKeys)
        btnApply.Visible = False
        ListView1.Items(0).Selected = True
        ShowSettingsControl(CType(ListView1.Items(0).Tag, SettingsControlHolder))
        MyBase.ShowDialog(owner)
        Return mSaved
    End Function

    Private Sub AddTab(ByVal control As Framework.Settings.ISettingsControl)
        Dim clsHolder As New SettingsControlHolder
        clsHolder.Control = control
        clsHolder.IsLoaded = False
        clsHolder.Name = control.DisplayName
        clsHolder.UserControl = control.GetUserControl

        Dim clsImage As Drawing.Image = control.DisplayImage
        If clsImage IsNot Nothing Then
            ilTabs.Images.Add(control.Key, clsImage)
        End If

        With ListView1.Items.Add(control.DisplayName)
            .Tag = clsHolder
            If clsImage IsNot Nothing Then .ImageKey = control.Key
        End With
        With clsHolder.UserControl
            .Visible = False
            .Dock = DockStyle.Fill
        End With
        mHolders.Add(control.Key, clsHolder)
        Panel1.Controls.Add(clsHolder.UserControl)
    End Sub


    Private Class SettingsControlHolder
        Public Name As String
        Public IsLoaded As Boolean
        Public Control As Framework.Settings.ISettingsControl
        Public UserControl As System.Windows.Forms.UserControl
    End Class

    Private Sub ListView1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListView1.SelectedIndexChanged
        If ListView1.SelectedItems.Count = 0 Then
            ShowSettingsControl(Nothing)
        Else
            Dim clsHolder As SettingsControlHolder = CType(ListView1.SelectedItems(0).Tag, SettingsControlHolder)
            ShowSettingsControl(clsHolder)
        End If
    End Sub

    Private Sub ShowSettingsControl(ByVal holder As SettingsControlHolder)
        If holder Is mCurrent Then Return
        If holder IsNot Nothing Then
            If Not holder.IsLoaded Then
                holder.Control.LoadSettings()
                holder.IsLoaded = True
                holder.Control.BeforeShow()
            End If
            holder.UserControl.Visible = True
        End If
        If mCurrent IsNot Nothing Then
            mCurrent.UserControl.Visible = False
            mCurrent = Nothing
        End If
        mCurrent = holder
    End Sub

    Private Sub btnApply_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnApply.Click
        Try
            Apply()
        Catch ex As Exception
            Framework.Misc.HandleException(Me, ex)
        End Try
    End Sub
    Private Function Apply() As Boolean
        Dim blnInvalid As Boolean = False
        ErrorProvider1.Clear()
        For Each clsHolder As SettingsControlHolder In mHolders.Values
            If clsHolder.IsLoaded Then
                If clsHolder.Control.NeedsSave Then
                    Dim clsEP As New Framework.ErrorHandling.ErrorProviderEx(ErrorProvider1)
                    clsHolder.Control.ValidateSettings(clsEP)
                    If clsEP.Count > 0 Then
                        blnInvalid = True
                        ShowSettingsControl(clsHolder)
                        Exit For
                    End If
                End If
            End If
        Next
        If Not blnInvalid Then
            Using t As New TransactionScope
                For Each clsHolder As SettingsControlHolder In mHolders.Values
                    If clsHolder.IsLoaded Then
                        If clsHolder.Control.NeedsSave Then
                            clsHolder.Control.SaveSettings(t)
                        End If
                    End If
                Next
                t.Complete()
            End Using
            For Each clsHolder As SettingsControlHolder In mHolders.Values
                If clsHolder.IsLoaded Then clsHolder.Control.SaveCompleted()
            Next
            Return True
        Else
            Return False
        End If
    End Function

    Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
        Try
            If Apply() Then
                mSaved = True
                Me.Close()
            End If
        Catch ex As Exception
            Framework.Misc.HandleException(Me, ex)
        End Try
    End Sub

    Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
        Me.Close()
    End Sub
    Private Function IsOkToCloseDialog() As Boolean
        If Not IsDirty() Then
            Return True
        Else
            Select Case MessageBox.Show(Me, "Save changes?", "Settings", MessageBoxButtons.YesNoCancel)
                Case Windows.Forms.DialogResult.Yes
                    Return Apply()
                Case Windows.Forms.DialogResult.No
                    Return True
                Case Else
                    Return False
            End Select
        End If
    End Function

    Private Function IsDirty() As Boolean
        For Each clsHolder As SettingsControlHolder In mHolders.Values
            If clsHolder.IsLoaded Then
                If clsHolder.Control.NeedsSave Then Return True
            End If
        Next
        Return False
    End Function

    Private Sub FSettings_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        For Each clsHolder As SettingsControlHolder In mHolders.Values
            If clsHolder.IsLoaded Then clsHolder.Control.AfterClose()
        Next
    End Sub

    Private Sub FSettings_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        Try
            e.Cancel = Not IsOkToCloseDialog()
        Catch ex As Exception
            Framework.Misc.HandleException(Me, ex)
        End Try
    End Sub

    Private Sub FSettings_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Me.Icon = Framework.My.Resources.Buddy
    End Sub
End Class